#if defined (RAMS_MPI)

!--------------------------------------------------------------------

subroutine parf_init_mpi(machnum, machsize)

  implicit none
  include 'mpif.h'
  integer, intent(out) :: machnum, machsize
  integer :: ierr

  call MPI_Init(ierr)
  if(ierr /= MPI_Success) then
     call fatal_error("Error in MPI_Init")
  endif

  call MPI_Comm_rank(MPI_COMM_WORLD, machnum, ierr)
  if(ierr /= MPI_Success) then
     call fatal_error("Error in MPI_Comm_rank")
  endif

  call MPI_Comm_size(MPI_COMM_WORLD, machsize, ierr)
  if(ierr /= MPI_Success) then
     call fatal_error("Error in MPI_Comm_size")
  endif
  
end subroutine parf_init_mpi

!--------------------------------------------------------------------

subroutine parf_exit_mpi()

  implicit none
  include 'mpif.h'
  integer :: ierr

  call MPI_Finalize(ierr)
  if(ierr /= MPI_Success) then
     call fatal_error("Error in MPI_Finalize")
  endif

end subroutine parf_exit_mpi

! -------------------------------------------------------------------

subroutine parf_error()

  implicit none
  include 'mpif.h'
  integer :: ierr

  call MPI_Abort(MPI_COMM_WORLD, 1, ierr)

end subroutine parf_error

!--------------------------------------------------------------------

subroutine parf_send_int(buff, buff_len, dest_host, tag)

  implicit none

  include 'mpif.h'

  ! Arguments:
  integer, intent(in)  :: buff_len, dest_host, tag
  integer, intent(in)  :: buff(buff_len)
  ! Local Variables:
  integer              :: ierr, ierr_b, rank
  character(len=20)    :: string

  call MPI_send(buff, buff_len, MPI_Integer, dest_host, tag, &
       MPI_COMM_WORLD, ierr)

  if(ierr /= MPI_Success) then
     call MPI_Comm_rank(MPI_COMM_WORLD, rank, ierr_b)
     write(string,FMT='(I6.6,X,I8)') rank, ierr
     call fatal_error("Error in parf_send_int: rank, ierr="//trim(string))
  endif


end subroutine parf_send_int

!--------------------------------------------------------------------

subroutine parf_get_int(buff, buff_len, source_host, tag)

  implicit none

  include 'mpif.h'

  ! Arguments:
  integer, intent(in)  :: buff_len, source_host, tag
  real,    intent(out) :: buff(buff_len)
  ! Local Variables:
  integer              :: ierr, ierr_b, rank
  character(len=20)    :: string
  integer              :: status(MPI_STATUS_SIZE)
       
  call MPI_recv(buff, buff_len, MPI_Integer, source_host, tag, &
       MPI_COMM_WORLD, status, ierr)

  if(ierr /= MPI_Success) then
     call MPI_Comm_rank(MPI_COMM_WORLD, rank, ierr_b)
     write(string,FMT='(I6.6,X,I8)') rank, ierr
     call fatal_error("Error in parf_get_int: rank, ierr="//trim(string))
  endif

end subroutine parf_get_int

!--------------------------------------------------------------------

subroutine parf_send_real(buff, buff_len, dest_host, tag)

  implicit none

  include 'mpif.h'

  ! Arguments:
  integer, intent(in)  :: buff_len, dest_host, tag
  real,    intent(in)  :: buff(buff_len)
  ! Local Variables:
  integer              :: ierr, ierr_b, rank
  character(len=20)    :: string

  call MPI_send(buff, buff_len, MPI_Real, dest_host, tag, &
       MPI_COMM_WORLD, ierr)

  if(ierr /= MPI_Success) then
     call MPI_Comm_rank(MPI_COMM_WORLD, rank, ierr_b)
     write(string,FMT='(I6.6,X,I8)') rank, ierr
     call fatal_error("Error in parf_send_real: rank, ierr="//trim(string))
  endif


end subroutine parf_send_real

!--------------------------------------------------------------------

subroutine parf_get_real(buff, buff_len, source_host, tag)

  implicit none

  include 'mpif.h'

  ! Arguments:
  integer, intent(in)  :: buff_len, source_host, tag
  real,    intent(out) :: buff(buff_len)
  ! Local Variables:
  integer              :: ierr, ierr_b, rank
  character(len=20)    :: string
  integer              :: status(MPI_STATUS_SIZE)
       
  call MPI_recv(buff, buff_len, MPI_Real, source_host, tag, &
       MPI_COMM_WORLD, status, ierr)

  if(ierr /= MPI_Success) then
     call MPI_Comm_rank(MPI_COMM_WORLD, rank, ierr_b)
     write(string,FMT='(I6.6,X,I8)') rank, ierr
     call fatal_error("Error in parf_get_real: rank, ierr="//trim(string))
  endif

end subroutine parf_get_real

!--------------------------------------------------------------------

subroutine parf_send_block(buff, buff_len, dest_host, tag)

  implicit none

  include 'mpif.h'

  ! Arguments:
  integer, intent(in)  :: buff_len, dest_host, tag
  real,    intent(in)  :: buff(buff_len)
  ! Local Variables:
  integer              :: ierr, ierr_b, rank
  character(len=20)    :: string

  call MPI_send(buff, buff_len, MPI_Packed, dest_host, tag, &
       MPI_COMM_WORLD, ierr)

  if(ierr /= MPI_Success) then
     call MPI_Comm_rank(MPI_COMM_WORLD, rank, ierr_b)
     write(string,FMT='(I6.6,X,I8)') rank, ierr
     call fatal_error("Error in parf_send_block: rank, ierr="//trim(string))
  endif

end subroutine parf_send_block

!--------------------------------------------------------------------

subroutine parf_get_block(buff, buff_len, source_host, tag)

  implicit none

  include 'mpif.h'

  ! Arguments:
  integer, intent(in)  :: buff_len, source_host, tag
  real,    intent(out) :: buff(buff_len)
  ! Local Variables:
  integer              :: ierr, ierr_b, rank
  character(len=20)    :: string
  integer              :: status(MPI_STATUS_SIZE)
       
  call MPI_recv(buff, buff_len, MPI_Packed, source_host, tag, &
       MPI_COMM_WORLD, status, ierr)

  if(ierr /= MPI_Success) then
     call MPI_Comm_rank(MPI_COMM_WORLD, rank, ierr_b)
     write(string,FMT='(I6.6,X,I8)') rank, ierr
     call fatal_error("Error in parf_get_block: rank, ierr="//trim(string))
  endif

end subroutine parf_get_block

!--------------------------------------------------------------------

subroutine parf_get_block_any(buff, buff_len, tag, host_msg)

  implicit none

  include 'mpif.h'

  ! Arguments:
  integer, intent(in)  :: buff_len, tag
  real,    intent(out) :: buff(buff_len)
  integer, intent(out) :: host_msg
  ! Local Variables:
  integer              :: ierr, ierr_b, rank
  character(len=20)    :: string
  integer              :: status(MPI_STATUS_SIZE)
       
  call MPI_recv(buff, buff_len, MPI_Packed, MPI_ANY_SOURCE, tag, &
       MPI_COMM_WORLD, status, ierr)

  if(ierr /= MPI_Success) then
     call MPI_Comm_rank(MPI_COMM_WORLD, rank, ierr_b)
     write(string,FMT='(I6.6,X,I8)') rank, ierr
     call fatal_error("Error in parf_get_block: rank, ierr="//trim(string))
  endif

  host_msg = status(MPI_SOURCE)

end subroutine parf_get_block_any

!--------------------------------------------------------------------

subroutine parf_get_noblock(buff, buff_len, source_host, tag, request)

  implicit none

  include 'mpif.h'

  ! Arguments:
  integer, intent(in)  :: buff_len, source_host, tag
  real,    intent(out) :: buff(buff_len)
  integer, intent(out) :: request
  ! Local Variables:
  integer              :: ierr, ierr_b, rank
  character(len=20)    :: string


  call MPI_Irecv(buff, buff_len, MPI_PACKED, source_host, tag, &
       MPI_COMM_WORLD, request, ierr)

  if(ierr /= MPI_Success) then
     call MPI_Comm_rank(MPI_COMM_WORLD, rank, ierr_b)
     write(string,FMT='(I6.6,X,I8,X,I8)') rank, request, ierr
     call fatal_error("Error in parf_get_noblock: rank, request, ierr="//trim(string))
  endif


end subroutine parf_get_noblock

!--------------------------------------------------------------------

subroutine parf_get_noblock_real(buff, buff_len, source_host, tag, request)

  implicit none

  include 'mpif.h'

  ! Arguments:
  integer, intent(in)  :: buff_len, source_host, tag
  real,    intent(out) :: buff(buff_len)
  integer, intent(out) :: request
  ! Local Variables:
  integer              :: ierr, ierr_b, rank
  character(len=20)    :: string


  call MPI_Irecv(buff, buff_len, MPI_REAL, source_host, tag, &
       MPI_COMM_WORLD, request, ierr)

  if(ierr /= MPI_Success) then
     call MPI_Comm_rank(MPI_COMM_WORLD, rank, ierr_b)
     write(string,FMT='(I6.6,X,I8,X,I8)') rank, request, ierr
     call fatal_error("Error in parf_get_noblock: rank, request, ierr="//trim(string))
  endif


end subroutine parf_get_noblock_real

!--------------------------------------------------------------------

subroutine parf_get_noblock_logical(buff, buff_len, source_host, tag, request)

  implicit none

  include 'mpif.h'

  ! Arguments:
  integer, intent(in)  :: buff_len, source_host, tag
  logical,    intent(out) :: buff(buff_len)
  integer, intent(out) :: request
  ! Local Variables:
  integer              :: ierr, ierr_b, rank
  character(len=20)    :: string


  call MPI_Irecv(buff, buff_len, MPI_PACKED, source_host, tag, &
       MPI_COMM_WORLD, request, ierr)

  if(ierr /= MPI_Success) then
     call MPI_Comm_rank(MPI_COMM_WORLD, rank, ierr_b)
     write(string,FMT='(I6.6,X,I8,X,I8)') rank, request, ierr
     call fatal_error("Error in parf_get_noblock: rank, request, ierr="//trim(string))
  endif


end subroutine parf_get_noblock_logical
!--------------------------------------------------------------------

subroutine parf_get_noblock_int(buff, buff_len, source_host, tag, request)

  implicit none

  include 'mpif.h'

  ! Arguments:
  integer, intent(in)  :: buff_len, source_host, tag
  integer,    intent(out) :: buff(buff_len)
  integer, intent(out) :: request
  ! Local Variables:
  integer              :: ierr, ierr_b, rank
  character(len=20)    :: string


  call MPI_Irecv(buff, buff_len, MPI_PACKED, source_host, tag, &
       MPI_COMM_WORLD, request, ierr)

  if(ierr /= MPI_Success) then
     call MPI_Comm_rank(MPI_COMM_WORLD, rank, ierr_b)
     write(string,FMT='(I6.6,X,I8,X,I8)') rank, request, ierr
     call fatal_error("Error in parf_get_noblock: rank, request, ierr="//trim(string))
  endif


end subroutine parf_get_noblock_int
!--------------------------------------------------------------------

subroutine parf_send_noblock(buff, buff_len, dest_host, tag, request)

  implicit none

  include 'mpif.h'

  ! Arguments:
  integer, intent(in)  :: buff_len, dest_host, tag
  real,    intent(in)  :: buff(buff_len)
  integer, intent(out) :: request
  ! Local Variables:
  integer              :: ierr, ierr_b, rank
  character(len=20)    :: string

  call MPI_Isend(buff, buff_len, MPI_Packed, dest_host, tag, &
       MPI_COMM_WORLD, request, ierr)

  if(ierr /= MPI_Success) then
     call MPI_Comm_rank(MPI_COMM_WORLD, rank, ierr_b)
     write(string,FMT='(I6.6,X,I8,X,I8)') rank, request, ierr
     call fatal_error("Error in parf_send_noblock: rank, request, ierr="//&
          trim(string))
  endif

end subroutine parf_send_noblock

!--------------------------------------------------------------------

subroutine parf_send_noblock_logical(buff, buff_len, dest_host, tag, request)

  implicit none

  include 'mpif.h'

  ! Arguments:
  integer, intent(in)  :: buff_len, dest_host, tag
  logical,    intent(in)  :: buff(buff_len)
  integer, intent(out) :: request
  ! Local Variables:
  integer              :: ierr, ierr_b, rank
  character(len=20)    :: string

  call MPI_Isend(buff, buff_len, MPI_Packed, dest_host, tag, &
       MPI_COMM_WORLD, request, ierr)

  if(ierr /= MPI_Success) then
     call MPI_Comm_rank(MPI_COMM_WORLD, rank, ierr_b)
     write(string,FMT='(I6.6,X,I8,X,I8)') rank, request, ierr
     call fatal_error("Error in parf_send_noblock: rank, request, ierr="//&
          trim(string))
  endif

end subroutine parf_send_noblock_logical

!--------------------------------------------------------------------
!--------------------------------------------------------------------

subroutine parf_send_noblock_real(buff, buff_len, dest_host, tag, request)

  implicit none

  include 'mpif.h'

  ! Arguments:
  integer, intent(in)  :: buff_len, dest_host, tag
  real,    intent(in)  :: buff(buff_len)
  integer, intent(out) :: request
  ! Local Variables:
  integer              :: ierr, ierr_b, rank
  character(len=20)    :: string

  call MPI_Isend(buff, buff_len, MPI_REAL, dest_host, tag, &
       MPI_COMM_WORLD, request, ierr)

  if(ierr /= MPI_Success) then
     call MPI_Comm_rank(MPI_COMM_WORLD, rank, ierr_b)
     write(string,FMT='(I6.6,X,I8,X,I8)') rank, request, ierr
     call fatal_error("Error in parf_send_noblock: rank, request, ierr="//&
          trim(string))
  endif

end subroutine parf_send_noblock_real

!--------------------------------------------------------------------

subroutine parf_send_noblock_int(buff, buff_len, dest_host, tag, request)

  implicit none

  include 'mpif.h'

  ! Arguments:
  integer, intent(in)  :: buff_len, dest_host, tag
  integer,    intent(in)  :: buff(buff_len)
  integer, intent(out) :: request
  ! Local Variables:
  integer              :: ierr, ierr_b, rank
  character(len=20)    :: string

  call MPI_Isend(buff, buff_len, MPI_Packed, dest_host, tag, &
       MPI_COMM_WORLD, request, ierr)

  if(ierr /= MPI_Success) then
     call MPI_Comm_rank(MPI_COMM_WORLD, rank, ierr_b)
     write(string,FMT='(I6.6,X,I8,X,I8)') rank, request, ierr
     call fatal_error("Error in parf_send_noblock: rank, request, ierr="//&
          trim(string))
  endif

end subroutine parf_send_noblock_int
!--------------------------------------------------------------------

subroutine parf_wait(request, status)

  implicit none

  include 'mpif.h'

  ! Arguments:
  integer, intent(inout) :: request
  integer, intent(out)   :: status(MPI_STATUS_SIZE)
  ! Local Variables:
  integer                :: ierr, ierr_b, rank
  character(len=20)      :: string

  call MPI_Wait(request, status, ierr)

  if(ierr /= MPI_Success) then
     call MPI_Comm_rank(MPI_COMM_WORLD, rank, ierr_b)
     write(string,FMT='(I6.6,X,I8,X,I8)') rank, request, ierr
     call fatal_error("Error in parf_wait: rank, request, ierr="//trim(string))
  endif

end subroutine parf_wait

!--------------------------------------------------------------------

subroutine parf_wait_nostatus(request)

  implicit none

  include 'mpif.h'

  ! Arguments:
  integer, intent(inout) :: request
  ! Local Variables:
  integer                :: status(MPI_STATUS_SIZE)
  integer                :: ierr, ierr_b, rank
  character(len=20)      :: string

  call MPI_Wait(request, status, ierr)

  if(ierr /= MPI_Success) call fatal_error("Error in parf_wait")

  if(ierr /= MPI_Success) then
     call MPI_Comm_rank(MPI_COMM_WORLD, rank, ierr_b)
     write(string,FMT='(I6.6,X,I8,X,I8)') rank, request, ierr
     call fatal_error("Error in parf_wait_nostatus: rank, request, ierr="//&
          trim(string))
  endif

end subroutine parf_wait_nostatus

!--------------------------------------------------------------------

subroutine parf_pack_int(in_buff, in_buff_len, &
     out_buff, out_buff_len, position)

  implicit none

  include 'mpif.h'

  ! Arguments:
  integer, intent(in)    :: in_buff_len, out_buff_len
  integer, intent(in)    :: in_buff(in_buff_len)
  real,    intent(inout) :: out_buff(out_buff_len)
  integer, intent(inout) :: position
  ! Local Variables:
  integer                :: ierr, ierr_b, rank
  character(len=20)      :: string

  call MPI_Pack(in_buff, in_buff_len, MPI_INTEGER, out_buff, out_buff_len, &
       position, MPI_COMM_WORLD, ierr)

  if(ierr /= MPI_Success) then
     call MPI_Comm_rank(MPI_COMM_WORLD, rank, ierr_b)
     write(string,FMT='(I6.6,X,I8)') rank, ierr
     call fatal_error("Error in parf_pack_int: rank, ierr="//trim(string))
  endif

end subroutine parf_pack_int

!--------------------------------------------------------------------

subroutine parf_pack_real(in_buff, in_buff_len, &
     out_buff, out_buff_len, position)

  implicit none

  include 'mpif.h'

  ! Arguments:
  integer, intent(in)    :: in_buff_len, out_buff_len
  real,    intent(in)    :: in_buff(in_buff_len)
  real,    intent(inout) :: out_buff(out_buff_len)
  integer, intent(inout) :: position
  ! Local Variables:
  integer                :: ierr, ierr_b, rank
  character(len=20)      :: string

  call MPI_Pack(in_buff, in_buff_len, MPI_REAL, out_buff, out_buff_len, &
       position, MPI_COMM_WORLD, ierr)

  if(ierr /= MPI_Success) then
     call MPI_Comm_rank(MPI_COMM_WORLD, rank, ierr_b)
     write(string,FMT='(I6.6,X,I8)') rank, ierr
     call fatal_error("Error in parf_pack_real: rank, ierr="//trim(string))
  endif

end subroutine parf_pack_real

!--------------------------------------------------------------------

subroutine parf_pack_char(in_buff, in_buff_len, &
     out_buff, out_buff_len, position)

  implicit none

  include 'mpif.h'

  ! Arguments:
  integer, intent(in)    :: in_buff_len, out_buff_len
!!$  character, intent(in)  :: in_buff(in_buff_len)
  character (len=in_buff_len), intent(in) :: in_buff
  real,    intent(inout) :: out_buff(out_buff_len)
  integer, intent(inout) :: position
  ! Local Variables:
  integer                :: ierr, ierr_b, rank
  character(len=20)      :: string

  call MPI_Pack(in_buff, in_buff_len, MPI_CHARACTER, out_buff, out_buff_len, &
       position, MPI_COMM_WORLD, ierr)

  if(ierr /= MPI_Success) then
     call MPI_Comm_rank(MPI_COMM_WORLD, rank, ierr_b)
     write(string,FMT='(I6.6,X,I8)') rank, ierr
     call fatal_error("Error in parf_pack_char: rank, ierr="//trim(string))
  endif

end subroutine parf_pack_char

!--------------------------------------------------------------------

subroutine parf_pack_char_vec(in_buff, in_buff_len, in_buff_chars, &
     out_buff, out_buff_len, position)

  implicit none

  include 'mpif.h'

  ! Arguments:
  integer, intent(in)                       :: in_buff_len, out_buff_len, &
       in_buff_chars
!!$  character, intent(in) :: in_buff(in_buff_len)
  character (len=in_buff_chars), intent(in) :: in_buff(in_buff_len)
  real,    intent(inout)                    :: out_buff(out_buff_len)
  integer, intent(inout)                    :: position
  ! Local Variables:
  integer                :: ierr, ierr_b, rank
  character(len=20)      :: string

  call MPI_Pack(in_buff, (in_buff_len*in_buff_chars), MPI_CHARACTER, &
       out_buff, out_buff_len, &
       position, MPI_COMM_WORLD, ierr)

  if(ierr /= MPI_Success) then
     call MPI_Comm_rank(MPI_COMM_WORLD, rank, ierr_b)
     write(string,FMT='(I6.6,X,I8)') rank, ierr
     call fatal_error("Error in parf_pack_char_vec: rank, ierr="//trim(string))
  endif

end subroutine parf_pack_char_vec

!--------------------------------------------------------------------

subroutine parf_unpack_int(in_buff, in_buff_len, position, &
     out_buff, out_buff_len)

  implicit none

  include 'mpif.h'

  ! Arguments:
  integer, intent(in)    :: in_buff_len, out_buff_len
  real,    intent(in)    :: in_buff(in_buff_len)
  integer, intent(inout) :: out_buff(out_buff_len)
  integer, intent(inout) :: position
  ! Local Variables:
  integer                :: ierr, ierr_b, rank
  character(len=20)      :: string

  call MPI_Unpack(in_buff, in_buff_len, position, out_buff, out_buff_len, &
       MPI_INTEGER, MPI_COMM_WORLD, ierr)

  if(ierr /= MPI_Success) then
     call MPI_Comm_rank(MPI_COMM_WORLD, rank, ierr_b)
     write(string,FMT='(I6.6,X,I8)') rank, ierr
     call fatal_error("Error in parf_unpack_int: rank, ierr="//trim(string))
  endif

end subroutine parf_unpack_int

!--------------------------------------------------------------------

subroutine parf_unpack_real(in_buff, in_buff_len, position, &
     out_buff, out_buff_len)

  implicit none

  include 'mpif.h'

  ! Arguments:
  integer, intent(in)    :: in_buff_len, out_buff_len
  real,    intent(in)    :: in_buff(in_buff_len)
  real,    intent(inout) :: out_buff(out_buff_len)
  integer, intent(inout) :: position
  ! Local Variables:
  integer                :: ierr, ierr_b, rank
  character(len=20)      :: string

  call MPI_Unpack(in_buff, in_buff_len, position, out_buff, out_buff_len, &
       MPI_REAL, MPI_COMM_WORLD, ierr)

  if(ierr /= MPI_Success) then
     call MPI_Comm_rank(MPI_COMM_WORLD, rank, ierr_b)
     write(string,FMT='(I6.6,X,I8)') rank, ierr
     call fatal_error("Error in parf_unpack_real: rank, ierr="//trim(string))
  endif

end subroutine parf_unpack_real

!--------------------------------------------------------------------

subroutine parf_unpack_char(in_buff, in_buff_len, position, &
     out_buff, out_buff_len)

  implicit none

  include 'mpif.h'

  ! Arguments:
  integer, intent(in)                         :: in_buff_len, out_buff_len
  real,    intent(in)                         :: in_buff(in_buff_len)
  character (len=out_buff_len), intent(inout) :: out_buff
  integer, intent(inout)                      :: position
  ! Local Variables:
  integer                :: ierr, ierr_b, rank
  character(len=20)      :: string

  call MPI_Unpack(in_buff, in_buff_len, position, out_buff, out_buff_len, &
       MPI_CHARACTER, MPI_COMM_WORLD, ierr)

  if(ierr /= MPI_Success) then
     call MPI_Comm_rank(MPI_COMM_WORLD, rank, ierr_b)
     write(string,FMT='(I6.6,X,I8)') rank, ierr
     call fatal_error("Error in parf_unpack_char: rank, ierr="//trim(string))
  endif

end subroutine parf_unpack_char

!--------------------------------------------------------------------

subroutine parf_unpack_char_vec(in_buff, in_buff_len, position, &
     out_buff, out_buff_len, out_buff_chars)

  implicit none

  include 'mpif.h'

  ! Arguments:
  integer, intent(in)                           :: in_buff_len, out_buff_len, &
       out_buff_chars
  real,    intent(in)                           :: in_buff(in_buff_len)
  character (len=out_buff_chars), intent(inout) :: out_buff(out_buff_len)
  integer, intent(inout)                        :: position
  ! Local Variables:
  integer                :: ierr, ierr_b, rank
  character(len=20)      :: string

  call MPI_Unpack(in_buff, in_buff_len, position, &
       out_buff, (out_buff_len*out_buff_chars), &
       MPI_CHARACTER, MPI_COMM_WORLD, ierr)

  if(ierr /= MPI_Success) then
     call MPI_Comm_rank(MPI_COMM_WORLD, rank, ierr_b)
     write(string,FMT='(I6.6,X,I8)') rank, ierr
     call fatal_error("Error in parf_unpack_char_vec: rank, ierr="//&
          trim(string))
  endif

end subroutine parf_unpack_char_vec

!--------------------------------------------------------------------

subroutine parf_barrier(ibarrier)

  implicit none

  include 'mpif.h'

  ! Arguments:
  integer, intent(in) :: ibarrier
  ! Local Variables:
  integer             :: ierr, ierr_b, rank
  character(len=20)   :: string

  call MPI_Barrier(MPI_COMM_WORLD, ierr)

  if (ierr /= MPI_Success) then
     call MPI_Comm_rank(MPI_COMM_WORLD, rank, ierr_b)
     write(string,FMT='(I6.6,X,I6,X,I8)') rank, ibarrier, ierr
     call fatal_error("Error in parf_barrier: "//trim(string))
  endif

end subroutine parf_barrier

!--------------------------------------------------------------------

subroutine parf_pack_max_size(len, max_size)

  implicit none

  include 'mpif.h'

  ! Arguments:
  integer, intent(in)  :: len
  integer, intent(out) :: max_size
  ! Local Variables:
  integer              :: mpi_int_size, mpi_real_size
  integer              :: ierr, rank
  character(len=20)    :: string

  call MPI_Pack_size(len, MPI_INTEGER, MPI_COMM_WORLD, mpi_int_size, ierr)
  if (ierr /= MPI_Success) then
     call MPI_Comm_rank(MPI_COMM_WORLD, rank, ierr)
     write(string,FMT='(I6.6,X,I8)') rank, ierr
     call fatal_error("Error in parf_pack_max_size:A: "//trim(string))
  endif
  call MPI_Pack_size(len, MPI_REAL, MPI_COMM_WORLD, mpi_real_size, ierr)
  if (ierr /= MPI_Success) then
     call MPI_Comm_rank(MPI_COMM_WORLD, rank, ierr)
     write(string,FMT='(I6.6,X,I8)') rank, ierr
     call fatal_error("Error in parf_pack_max_size:B: "//trim(string))
  endif

  max_size = max(mpi_real_size, mpi_int_size)

  ! Extra lenght
  max_size = max_size + max_size/2

end subroutine parf_pack_max_size

!--------------------------------------------------------------------


! **************************************************************

#else ! No MPI - Serial Version

!--------------------------------------------------------------------

subroutine parf_init_mpi(machnum, machsize)

  implicit none
  integer, intent(out) :: machnum, machsize

  machnum  = 0
  machsize = 1
  
end subroutine parf_init_mpi

!--------------------------------------------------------------------

subroutine parf_exit_mpi()

  implicit none

end subroutine parf_exit_mpi

! -------------------------------------------------------------------

subroutine parf_error()

  implicit none

end subroutine parf_error

!--------------------------------------------------------------------

subroutine parf_send_int(buff, buff_len, dest_host, tag)

  implicit none
  ! Arguments:
  integer, intent(in)  :: buff_len, dest_host, tag
  integer, intent(in)  :: buff(buff_len)

end subroutine parf_send_int

!--------------------------------------------------------------------

subroutine parf_get_int(buff, buff_len, source_host, tag)

  implicit none
  ! Arguments:
  integer, intent(in) :: buff_len, source_host, tag
  real,    intent(in) :: buff(buff_len)

end subroutine parf_get_int

!--------------------------------------------------------------------

subroutine parf_send_real(buff, buff_len, dest_host, tag)

  implicit none
  ! Arguments:
  integer, intent(in)  :: buff_len, dest_host, tag
  real,    intent(in)  :: buff(buff_len)

end subroutine parf_send_real

!--------------------------------------------------------------------

subroutine parf_get_real(buff, buff_len, source_host, tag)

  implicit none
  ! Arguments:
  integer, intent(in) :: buff_len, source_host, tag
  real,    intent(in) :: buff(buff_len)

end subroutine parf_get_real

!--------------------------------------------------------------------

subroutine parf_send_block(buff, buff_len, dest_host, tag)

  implicit none
  ! Arguments:
  integer, intent(in)  :: buff_len, dest_host, tag
  real,    intent(in)  :: buff(buff_len)

end subroutine parf_send_block

!--------------------------------------------------------------------

subroutine parf_get_block(buff, buff_len, source_host, tag)

  implicit none
  ! Arguments:
  integer, intent(in) :: buff_len, source_host, tag
  real,    intent(in) :: buff(buff_len)

end subroutine parf_get_block

!--------------------------------------------------------------------

subroutine parf_get_block_any(buff, buff_len, tag, host_msg)

  implicit none
  ! Arguments:
  integer, intent(in)  :: buff_len, tag
  real,    intent(in)  :: buff(buff_len)
  integer, intent(out) :: host_msg

  host_msg = -1

end subroutine parf_get_block_any

!--------------------------------------------------------------------

subroutine parf_get_noblock(buff, buff_len, source_host, tag, request)

  implicit none
  ! Arguments:
  integer, intent(in)  :: buff_len, source_host, tag
  real,    intent(in)  :: buff(buff_len)
  integer, intent(out) :: request

  request = -1

end subroutine parf_get_noblock

!--------------------------------------------------------------------

subroutine parf_get_noblock_logical(buff, buff_len, source_host, tag, request)

  implicit none
  ! Arguments:
  integer, intent(in)  :: buff_len, source_host, tag
  logical,    intent(in)  :: buff(buff_len)
  integer, intent(out) :: request

  request = -1

end subroutine parf_get_noblock_logical

!--------------------------------------------------------------------

!--------------------------------------------------------------------

subroutine parf_send_noblock(buff, buff_len, dest_host, tag, request)

  implicit none
  ! Arguments:
  integer, intent(in)  :: buff_len, dest_host, tag
  real,    intent(in)  :: buff(buff_len)
  integer, intent(out) :: request

  request = -1

end subroutine parf_send_noblock

!--------------------------------------------------------------------

subroutine parf_wait(request, status)

  implicit none
  ! Arguments:
  integer, intent(inout) :: request
  integer, intent(in)    :: status(*)

end subroutine parf_wait

!--------------------------------------------------------------------

subroutine parf_wait_nostatus(request)

  implicit none
  ! Arguments:
  integer, intent(inout) :: request

end subroutine parf_wait_nostatus

!--------------------------------------------------------------------

subroutine parf_pack_int(in_buff, in_buff_len, &
     out_buff, out_buff_len, position)

  implicit none
  ! Arguments:
  integer, intent(in)    :: in_buff_len, out_buff_len
  integer, intent(in)    :: in_buff(in_buff_len)
  real,    intent(inout) :: out_buff(out_buff_len)
  integer, intent(in)    :: position

end subroutine parf_pack_int

!--------------------------------------------------------------------

subroutine parf_pack_real(in_buff, in_buff_len, &
     out_buff, out_buff_len, position)

  implicit none
  ! Arguments:
  integer, intent(in)    :: in_buff_len, out_buff_len
  real,    intent(in)    :: in_buff(in_buff_len)
  real,    intent(inout) :: out_buff(out_buff_len)
  integer, intent(in)    :: position

end subroutine parf_pack_real

!--------------------------------------------------------------------

subroutine parf_pack_char(in_buff, in_buff_len, &
     out_buff, out_buff_len, position)

  implicit none
  ! Arguments:
  integer, intent(in)    :: in_buff_len, out_buff_len
  character (len=in_buff_len), intent(in) :: in_buff
  real,    intent(inout) :: out_buff(out_buff_len)
  integer, intent(in)    :: position

end subroutine parf_pack_char

!--------------------------------------------------------------------

subroutine parf_pack_char_vec(in_buff, in_buff_len, in_buff_chars, &
     out_buff, out_buff_len, position)

  implicit none

  ! Arguments:
  integer, intent(in)                       :: in_buff_len, out_buff_len, &
       in_buff_chars
  character (len=in_buff_chars), intent(in) :: in_buff(in_buff_len)
  real,    intent(inout)                    :: out_buff(out_buff_len)
  integer, intent(inout)                    :: position

end subroutine parf_pack_char_vec

!--------------------------------------------------------------------

subroutine parf_unpack_int(in_buff, in_buff_len, position, &
     out_buff, out_buff_len)

  implicit none
  ! Arguments:
  integer, intent(in)    :: in_buff_len, out_buff_len
  real,    intent(in)    :: in_buff(in_buff_len)
  integer, intent(inout) :: out_buff(out_buff_len)
  integer, intent(in)    :: position

end subroutine parf_unpack_int

!--------------------------------------------------------------------

subroutine parf_unpack_real(in_buff, in_buff_len, position, &
     out_buff, out_buff_len)

  implicit none
  ! Arguments:
  integer, intent(in)    :: in_buff_len, out_buff_len
  real,    intent(in)    :: in_buff(in_buff_len)
  real,    intent(inout) :: out_buff(out_buff_len)
  integer, intent(in)    :: position

end subroutine parf_unpack_real

!--------------------------------------------------------------------

subroutine parf_unpack_char(in_buff, in_buff_len, position, &
     out_buff, out_buff_len)

  implicit none
  ! Arguments:
  integer, intent(in)    :: in_buff_len, out_buff_len
  character (len=in_buff_len), intent(in) :: in_buff
  real,    intent(inout) :: out_buff(out_buff_len)
  integer, intent(in)    :: position

end subroutine parf_unpack_char

!--------------------------------------------------------------------

subroutine parf_unpack_char_vec(in_buff, in_buff_len, position, &
     out_buff, out_buff_len, out_buff_chars)

  implicit none

  ! Arguments:
  integer, intent(in)                           :: in_buff_len, out_buff_len, &
       out_buff_chars
  real,    intent(in)                           :: in_buff(in_buff_len)
  character (len=out_buff_chars), intent(inout) :: out_buff(out_buff_len)
  integer, intent(inout)                        :: position

end subroutine parf_unpack_char_vec

!--------------------------------------------------------------------

subroutine parf_barrier(ibarrier)

  implicit none
  ! Arguments:
  integer, intent(in) :: ibarrier

end subroutine parf_barrier

!--------------------------------------------------------------------

subroutine parf_pack_max_size(len, max_size)

  implicit none
  ! Arguments:
  integer, intent(in)  :: len
  integer, intent(out) :: max_size

  max_size = 0

end subroutine parf_pack_max_size

!--------------------------------------------------------------------

#endif




